#pragma once

#include "znx_defs.h"
#include "znx_syscall.h"

extern volatile int64_t g_cache_time;   // global cache time


/* accurate to microseconds */
#define TIME_SECOND                   (1000 * TIME_MSECOND)
#define TIME_MSECOND                  (1000 * TIME_USECOND)
#define TIME_USECOND                  (1LL)


static inline int64_t
znx_usec_2_msec(int64_t usec)
{
    return usec / TIME_MSECOND;
}


static inline int64_t
znx_usec_2_sec(int64_t usec)
{
    return usec / TIME_SECOND;
}


static inline int64_t
znx_sec_2_usec(int64_t sec)
{
    return sec * TIME_SECOND;
}


static inline int64_t
znx_msec_2_usec(int64_t msec)
{
    return msec * TIME_MSECOND;
}


static inline int64_t
znx_ts_2_usec(const znx_timespec_t *ts)
{
    return znx_sec_2_usec((int64_t)ts->tv_sec) + (int64_t)(ts->tv_nsec / 1000);
}


static inline void
znx_usec_2_ts(int64_t usec, znx_timespec_t *ts)
{
    ts->tv_sec = (long)znx_usec_2_sec(usec);
    ts->tv_nsec = (long)(usec % TIME_SECOND) * 1000;
}


/**
 * @brief get global cache time
 * @return usec
 */
int64_t get_cache_time();



/**
 * @brief use clock_gettime to get latest time and update g_cache_time
 * 
 * @return usec
 */
int64_t get_latest_time();


#define ZNX_TIME_HTTP_TIME_SIZE                 sizeof("Mon, 28 Sep 1970 06:00:00 GMT")
#define ZNX_TIME_LOG_TIME_SIZE                  sizeof("2021/10/20 10:20:30")


int znx_http_time(int64_t time_sec, char *buf, size_t buf_size);

int znx_log_time(int64_t time_sec, char *buf, size_t buf_size);

// If the current thread does not call get_latest_time, this time will not be updated.
int znx_cache_http_time(u_char *buf, size_t buf_size);

//  If the current thread does not call get_latest_time, this time will not be updated.
int znx_cache_log_time(u_char *buf, size_t buf_size);

// If the current thread does not call get_latest_time, this time will not be updated.
znx_timespec_t get_cache_timespec();

// Format:
// Sunday, 06-Nov-94 08:49:37 GMT       RFC 822, updated by RFC 1123
// Sun, 06 Nov 1994 08:49:37 GMT        RFC 850, obsoleted by RFC 1036
// Sun Nov  6 08:49:37 1994             ANSI C's asctime() format
// If znx_parse_http_time retrun < 0, mean value format error.
int64_t znx_parse_http_time(u_char *value, size_t len);
